package com.duan.utils;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * @author lwh
 * @date 2020/2/17 14:48
 * @description 日期相关的工具类
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
	
    private static final String TIME_ZONE ="GMT+0800";
    private static final String FORMAT_DATE = "yyyy-MM-dd";
    private static final String FORMAT_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    private static final ZoneId ZONEID = ZoneId.of(ZoneId.SHORT_IDS.get("CTT"));
	private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

	public static String YYYY = "yyyy";

	public static String YYYY_MM = "yyyy-MM";

	public static String YYYY_MM_DD = "yyyy-MM-dd";

	public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

	private static String[] parsePatterns = {
			"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
			"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
			"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};





	public static final String getTime()
	{
		return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
	}

	public static final String dateTimeNow()
	{
		return dateTimeNow(YYYYMMDDHHMMSS);
	}

	public static final String dateTimeNow(final String format)
	{
		return parseDateToStr(format, new Date());
	}

	public static final String dateTime(final Date date)
	{
		return parseDateToStr(YYYY_MM_DD, date);
	}

	public static final String parseDateToStr(final String format, final Date date)
	{
		return new SimpleDateFormat(format).format(date);
	}

	public static final Date dateTime(final String format, final String ts)
	{
		try
		{
			return new SimpleDateFormat(format).parse(ts);
		}
		catch (ParseException e)
		{
			throw new RuntimeException(e);
		}
	}

	public static Date getCurDate()
	{
		return new Date();
	}

	/**
	 * 日期路径 即年/月/日 如2018/08/08
	 */
	public static final String datePath()
	{
		Date now = new Date();
		return DateFormatUtils.format(now, "yyyy/MM/dd");
	}

	/**
	 * 日期路径 即年/月/日 如20180808
	 */
	public static final String dateTime()
	{
		Date now = new Date();
		return DateFormatUtils.format(now, "yyyyMMdd");
	}



	/**
	 * 获取服务器启动时间
	 */
	public static Date getServerStartDate()
	{
		long time = ManagementFactory.getRuntimeMXBean().getStartTime();
		return new Date(time);
	}

	/**
	 * 计算相差天数
	 */
	public static int differentDaysByMillisecond(Date date1, Date date2)
	{
		return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
	}

	/**
	 * 计算两个时间差
	 */
	public static String getDatePoor(Date endDate, Date nowDate)
	{
		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		// long ns = 1000;
		// 获得两个时间的毫秒时间差异
		long diff = endDate.getTime() - nowDate.getTime();
		// 计算差多少天
		long day = diff / nd;
		// 计算差多少小时
		long hour = diff % nd / nh;
		// 计算差多少分钟
		long min = diff % nd % nh / nm;
		// 计算差多少秒//输出结果
		// long sec = diff % nd % nh % nm / ns;
		return day + "天" + hour + "小时" + min + "分钟";
	}

	/**
	 * 增加 LocalDateTime ==> Date
	 */
	public static Date toDate(LocalDateTime temporalAccessor)
	{
		ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
		return Date.from(zdt.toInstant());
	}

	/**
	 * 增加 LocalDate ==> Date
	 */
	public static Date toDate(LocalDate temporalAccessor)
	{
		LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
		ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
		return Date.from(zdt.toInstant());
	}
	/**
	 * 获得当前日期 格式 yyyy-MM-dd HH:mm:ss
	 */
	public static String getNowDate() {
		return formatter.format(Instant.now());
	}

	/**
	 * 时间戳转日期 格式 yyyy-MM-dd HH:mm:ss
	 */
	public static String getDate(long time) {
		LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(time/1000, (int) (time%1000), ZoneOffset.ofHours(8));
		return formatter.format(localDateTime);
	}

	/**
	 * 根据格式化字符显示日期
	 * @param date
	 * @param format
	 * @return
	 * @throws Exception
	 */
    public static String formatDate(Date date,String format) throws Exception{
    	DateFormat sdf = new SimpleDateFormat(format);
        String result = sdf.format(date);
        return result;
    } 
    /**
     * 根据格式化字符显示当前日期
     *
     * @param format 格式字符串
     * @return String 当前日期
     */
    public static String formatDate(String format) {
        return DateFormatUtils.format(getTimeInMillis(), format,
                TimeZone.getTimeZone(TIME_ZONE));
    }
   
    /**
     * 取得当前日期毫秒数
     *
     * @return long 当前日期毫秒数
     */
    public static long getTimeInMillis() {
    	Calendar cl1=Calendar.getInstance(TimeZone.getTimeZone(TIME_ZONE));
        return cl1.getTimeInMillis();
    }
    
    /**
     * 得到当前日期 yyyy-MM-dd HH:mm:ss
     *
     * @return String
     */
    public static String getCurrentDate() {
        return formatDate(FORMAT_DATE_TIME);
    }

	/**
	 * 将字符串按照格式转换成日期格式
	 * @param format
	 * @param date
	 * @return
	 */
	public static Date parseDate(SimpleDateFormat format, String date) {
		Date dt = null;
		try {
			format.setTimeZone(TimeZone.getTimeZone("GMT+0800"));
			format.setLenient(false);
			dt = format.parse(date);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return dt;
	}

	/**
	 * 将字符串转换成日期格式
	 * @param dateStr
	 * @return
	 */
	public static Date parseDate(String dateStr) {
		Date date = null;
		if (null == dateStr || 0 == dateStr.length()){
			return null;
		}

		if (dateStr.length() > 10){
			SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			date =parseDate(DATE_TIME_FORMAT,dateStr); 
		}else{
			SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
			date = parseDate(DATE_FORMAT,dateStr);			
		}
		
		return date;
	}
    /**
     * 
     * 得到时间yyyy-MM-dd HH:mm:ss
     * 把字符串换成特定格式的时间。
     * curdatetime 时间戳
     * dtype 单位
     * diff 数量
     * @return String
     */
    public static String getDateTime(String Dtype,int diff) {
       	String dateTime=null;
    	try{
            
    		Calendar calendar=Calendar.getInstance(TimeZone.getTimeZone(TIME_ZONE));
    		
    		if (Dtype.equalsIgnoreCase("D")){
    			calendar.add(Calendar.DATE, diff);
    		}else if (Dtype.equalsIgnoreCase("H")){
    			calendar.add(Calendar.HOUR, diff);
    		}else if (Dtype.equalsIgnoreCase("MIN")){
    			calendar.add(Calendar.MINUTE, diff);
    		}else if (Dtype.equalsIgnoreCase("S")){
    			calendar.add(Calendar.SECOND, diff);
    		}else if (Dtype.equalsIgnoreCase("M")){
    			calendar.add(Calendar.MONTH, diff);
    		}else if (Dtype.equalsIgnoreCase("Y")){
    			calendar.add(Calendar.YEAR, diff);
    		}

    		dateTime= DateUtils.formatDate(calendar.getTime(),"yyyy-MM-dd HH:mm:ss");
    		
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	
    	return dateTime;
    	
    }	
    /**
     * 
     * 得到时间yyyy-MM-dd HH:mm:ss
     * 把字符串换成特定格式的时间。
     * curdatetime 时间戳
     * dtype 单位
     * diff 数量
     * @return String
     */
    public static String getDateTime(String curDateTime,String Dtype,int diff) {
       	String dateTime=null;
    	try{
            Date cDateTime= DateUtils.parseDate(curDateTime);
            
    		Calendar calendar=Calendar.getInstance(TimeZone.getTimeZone(TIME_ZONE));
    		calendar.setTime(cDateTime);
    		
    		if (Dtype.equalsIgnoreCase("D")){
    			calendar.add(Calendar.DATE, diff);
    		}else if (Dtype.equalsIgnoreCase("H")){
    			calendar.add(Calendar.HOUR, diff);
    		}else if (Dtype.equalsIgnoreCase("MIN")){
    			calendar.add(Calendar.MINUTE, diff);
    		}else if (Dtype.equalsIgnoreCase("S")){
    			calendar.add(Calendar.SECOND, diff);
    		}else if (Dtype.equalsIgnoreCase("M")){
    			calendar.add(Calendar.MONTH, diff);
    		}else if (Dtype.equalsIgnoreCase("Y")){
    			calendar.add(Calendar.YEAR, diff);
    		}

    		dateTime= DateUtils.formatDate(calendar.getTime(),"yyyy-MM-dd HH:mm:ss");
    		
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	
    	return dateTime;
    	
    }
    /**
     * 得到当前日期 yyyy-MM-dd
     *
     * @return String
     */
    public static String getCurrentDay() {
        return formatDate(FORMAT_DATE);
    } 
    
    /**
     * 取得当前日期
     * 
     * @return java.sql.Date
     */
    public static Date getDate() {
    	Calendar cl1=Calendar.getInstance(TimeZone.getTimeZone(TIME_ZONE));
        return cl1.getTime();
    }

    public static long instant2systemTimeMillis(Instant instant) {
        return instant.toEpochMilli();
    }

    public static Instant systemTimeMillis2Instant(long systemTimeMillis) {
        Date date = new Date(systemTimeMillis);
        return date.toInstant();
    }

    public static Date instant2Date(Instant instant) {
        return new Date(instant.toEpochMilli());
    }

    public static Instant date2Instant(Date date) {
        return date.toInstant();
    }

    public static LocalDateTime instant2LocalDateTime(Instant instant) {
        return instant.atZone(ZONEID).toLocalDateTime();
    }

    public static Instant localDateTime2Instant(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZONEID).toInstant();
    }

    public static LocalDateTime date2LocalDateTime(Date date) {
        Instant instant = date2Instant(date);
        return instant.atZone(ZONEID).toLocalDateTime();
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        return instant2Date(localDateTime.atZone(ZONEID).toInstant());
    }
    public static LocalDateTime localDate2LocalDateTime(LocalDate localDate) {
        return localDate.atStartOfDay();
    } 
}
